package com.piece.core.framework.util.net;

import com.piece.core.framework.util.collection.ArrayUtil;
import com.piece.core.framework.util.string.StringUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

@Data
@NoArgsConstructor
public class URLPath {

    private List<String> segments;
    private boolean withEngTag;

    public static URLPath of(String pathStr, Charset charset) {
        URLPath urlPath = new URLPath();
        urlPath.parse(pathStr, charset);
        return urlPath;
    }

    public URLPath setWithEndTag(boolean withEngTag) {
        this.withEngTag = withEngTag;
        return this;
    }

    public String getSegment(int index) {
        return null != this.segments && index < this.segments.size() ? this.segments.get(index) : null;
    }

    public URLPath add(CharSequence segment) {
        this.addInternal(fixPath(segment), false);
        return this;
    }

    public URLPath addBefore(CharSequence segment) {
        this.addInternal(fixPath(segment), true);
        return this;
    }

    public URLPath parse(String path, Charset charset) {
        if (StringUtil.isNotEmpty(path)) {
            if (StringUtil.endsWith(path, "/")) {
                this.withEngTag = true;
            }

            path = fixPath(path);
            String[] split = StringUtil.split(path, "/");
            Iterator var4 = Arrays.stream(split).iterator();

            while(var4.hasNext()) {
                String seg = (String)var4.next();
                this.addInternal(URLDecoder.decode(seg, charset), false);
            }
        }

        return this;
    }

    public String build(Charset charset) {
        if (ArrayUtil.isEmpty(this.segments)) {
            return "";
        } else {
            StringBuilder builder = new StringBuilder();
            Iterator var3 = this.segments.iterator();

            while(var3.hasNext()) {
                String segment = (String)var3.next();
                builder.append('/').append(URLEncoder.PATH_SEGMENT.encode(segment, charset));
            }

            if (this.withEngTag || StringUtil.isEmpty(builder)) {
                builder.append('/');
            }

            return builder.toString();
        }
    }

    private void addInternal(CharSequence segment, boolean before) {
        if (null == this.segments) {
            this.segments = new LinkedList();
        }

        String seg = String.valueOf(segment);
        if (before) {
            this.segments.add(0, seg);
        } else {
            this.segments.add(seg);
        }
    }

    private static String fixPath(CharSequence path) {
        if ("/".contentEquals(path)) {
            return "";
        } else {
            String segmentStr = StringUtil.trim(String.valueOf(path));
            segmentStr = StringUtil.removeStart(segmentStr, "/");
            segmentStr = StringUtil.removeEnd(segmentStr, "/");
            segmentStr = StringUtil.trim(segmentStr);
            return segmentStr;
        }
    }
}